#ifndef __RISCV32_RTL_H__
#define __RISCV32_RTL_H__

#include "rtl/rtl.h"
#include "reg.h"

static inline void rtl_lr(rtlreg_t* dest, int r, int width) {
  if (r != 0) { rtl_mv(dest, &reg_l(r)); }
  else { rtl_li(dest, 0); }
}

static inline void rtl_sr(int r, const rtlreg_t *src1, int width) {
  if (r != 0) { rtl_mv(&reg_l(r), src1); }
}

static inline void rtl_csrr(rtlreg_t* dest, int r, int width) {
  if (r == CSR_SSTATUS){rtl_mv(dest, &reg_sstatus);}
  else if (r == CSR_STVEC){rtl_mv(dest, &reg_stvec);}
  else if (r == CSR_SEPC){rtl_mv(dest, &reg_sepc);}
  else if (r == CSR_SCAUSE){rtl_mv(dest, &reg_scause);}
  else if (r == CSR_SATP){rtl_mv(dest, &reg_satp);}
  else {assert(0);}
}

static inline void rtl_csrw(int r, const rtlreg_t *src1, int width) {
  if (r == CSR_SSTATUS){rtl_mv(&reg_sstatus , src1);}
  else if (r == CSR_STVEC){rtl_mv(&reg_stvec , src1);}
  else if (r == CSR_SEPC){rtl_mv(&reg_sepc , src1);}
  else if (r == CSR_SCAUSE){rtl_mv(&reg_scause , src1);}
  else if (r == CSR_SATP){rtl_mv(&reg_satp , src1);}
  else {assert(0);}
}

static inline void rtl_csrwi(int r, const int imm, int width) {
  if (r == CSR_SSTATUS){reg_sstatus = imm;}
  else if (r == CSR_STVEC){reg_stvec = imm;}
  else if (r == CSR_SEPC){reg_sepc = imm;}
  else if (r == CSR_SCAUSE){reg_scause = imm;}
  else if (r == CSR_SATP){reg_satp = imm;}
  else {assert(0);}
}

static inline void rtl_set(rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) {
  t0 = 1 << (*src2);
  *dest = *src1 | t0;
}

static inline void rtl_clear(rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) {
  t0 = ~(1 << (*src2));
  *dest = *src1 & t0;
}

#endif
